#include "cpu/exec/template-start.h"

//0x85 test
make_helper(test) {
    //解析参数
    int len = decode_rm2r_l(eip + 1);
    //取出操作数,根据第一个数的类型
    unsigned int mem1 = 0;
    unsigned int mem2 = 0;
    // Log("op_src->type = %d", op_src->type);

    switch (op_src->type) {
        case OP_TYPE_REG:
            // Log("op_dest->reg = %d", op_dest->reg);
            //获得寄存器的值
            switch (op_src->reg) {
                case 0:
                    mem1 = cpu.eax;
                    break;
                case 1:
                    mem1 = cpu.ecx;
                    break;
                case 2:
                    mem1 = cpu.edx;
                    break;
                case 3:
                    mem1 = cpu.ebx;
                    break;
                case 4:
                    mem1 = cpu.esp;
                    break;
                case 5:
                    mem1 = cpu.ebp;
                    break;
                case 6:
                    mem1 = cpu.esi;
                    break;
                case 7:
                    mem1 = cpu.edi;
                    break;
                default:
                    assert(0);
            }
            // Log("eax = %x", cpu.eax);
            // Log("mem1 = %x", mem1);
            break;
        case OP_TYPE_MEM:
            mem1 = swaddr_read(op_src->addr, DATA_BYTE);
            break;
        default:
            assert(0);
    }
    //取出第二个操作数
    // Log("op_dest->type = %d", op_dest->type);
    switch (op_dest->type) {
        case OP_TYPE_REG:
            //获得寄存器的值
            switch (op_dest->reg) {
                case 0:
                    mem2 = cpu.eax;
                    break;
                case 1:
                    mem2 = cpu.ecx;
                    break;
                case 2:
                    mem2 = cpu.edx;
                    break;
                case 3:
                    mem2 = cpu.ebx;
                    break;
                case 4:
                    mem2 = cpu.esp;
                    break;
                case 5:
                    mem2 = cpu.ebp;
                    break;
                case 6:
                    mem2 = cpu.esi;
                    break;
                case 7:
                    mem2 = cpu.edi;
                    break;
                default:
                    assert(0);
            }
            break;
        case OP_TYPE_MEM:
            mem2 = swaddr_read(op_dest->addr, DATA_BYTE);
            break;
        case OP_TYPE_IMM:
            mem2 = op_dest->val;
            break;
    }
    // Log("cpu.eax = %x", cpu.eax);
    //进行与操作
    // Log("mem1 = %x, mem2 = %x", mem1, mem2);
    unsigned int result = mem1 & mem2;
    // Log("result = %x", result);
    if (result == 0) {
        cpu.eflags.ZF = 1;
    } else {
        cpu.eflags.ZF = 0;
    }
    cpu.eflags.SF = result >> 31;
    cpu.eflags.PF = (result & 1) ^ (result >> 1) ^ (result >> 2) ^ (result >> 3) ^ (result >> 4) ^ (result >> 5) ^ (result >> 6) ^ (result >> 7);
    cpu.eflags.CF = 0;
    cpu.eflags.OF = 0;


    return len + 1;
}